using System;
using System.Reflection;

using NUnit.Framework;

namespace Rsdn.SmartApp
{
	[TestFixture]
	public class SchemaScanTest
	{
		private ServiceManager _svcManager;
		private ExtensionManager _extManager;
		private TypeSchemaStrategy _schemaStrat;

		[SetUp]
		protected void SetUp()
		{
			_svcManager = new ServiceManager();
			_extManager = new ExtensionManager(_svcManager);
			_schemaStrat = new TypeSchemaStrategy(_svcManager, new DefaultScanner());
		}

		[Test]
		public void SchemaTypeRegistration()
		{
			_extManager.Scan(
				Assembly.GetExecutingAssembly().GetTypes(), 
				_schemaStrat);
			IRegElementsService<TypeSchemaInfo> svc =
				_extManager.GetService<IRegElementsService<TypeSchemaInfo>>();
			Assert.IsNotNull(svc);
			TypeSchemaInfo testSchemaInfo = null;
			foreach (TypeSchemaInfo sti in svc.GetRegisteredElements())
				if (sti.Type == typeof (TestSchemaType))
				{
					testSchemaInfo = sti;
					break;
				}
			Assert.IsNotNull(testSchemaInfo);
			Assert.IsNotNull(testSchemaInfo.TypeSchema);
			Assert.AreEqual(testSchemaInfo.TypeSchema.Name, typeof (TestSchemaType).FullName);
			ISchemaProperty nameProp = null;
			foreach (ISchemaProperty sp in testSchemaInfo.TypeSchema.Properties)
				if (sp.Name == "Name")
				{
					nameProp = sp;
					break;
				}
			Assert.IsNotNull(nameProp);
		}
		
		[Test]
		[ExpectedException(typeof (ArgumentNullException),
			"Value cannot be null.\r\nParameter name: type")]
		public void ScannerParamNull()
		{
			ITypeSchemaScanner scanner = new DefaultScanner();
			scanner.GetTypeSchema(null);
		}

		[Test]
		[ExpectedException(typeof(ApplicationException), "Type must be marked by "
			+ "Rsdn.SmartApp.TestSchemaAttribute")]
		public void NoAttributeOnType()
		{
			ITypeSchemaScanner scanner = new DefaultScanner();
			scanner.GetTypeSchema(typeof (string));
		}
	}
}
